﻿using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

using BeachRunner.Utility;
using BeachRunner.Tileengine;
using BeachRunner.BeachRunner;
using Microsoft.Xna.Framework.Media;


namespace BeachRunner.Menu
{
    /// <summary>
    /// MainMenuPage
    /// 
    /// Author: Arne Blumentritt, Mathias Müller
    /// </summary>
    public class MainMenuPage : Page
    {
        // Spalten für jedes Level
        private Vector2 positionLevel1;
        private Vector2 positionLevel2;
        private Vector2 positionLevel3;
        private Vector2 positionLevel4;

        // Buttons
        private Button buttonLevel1;
        private Button buttonLevel2;
        private Button buttonLevel3;
        private Button buttonLevel4;
        private Button buttonHelp;
        private Button buttonConfigSoundEffects;
        private Button buttonConfigSoundBackground;
        private Texture2D buttonBgLevel1;
        private Texture2D buttonBgLevel2;
        private Texture2D buttonBgLevel3;
        private Texture2D buttonBgLevel4;
        private Texture2D buttonHelpBg;
        private Texture2D buttonConfigActiveBg;
        private Texture2D buttonConfigInactiveBg;
        private Vector2 buttonHelpPosition;
        private Vector2 buttonConfigSoundEffectsPosition;
        private Vector2 buttonConfigSoundBackgroundPosition;

        // Highscore
        private Texture2D highscoreBg;
        private List<Highscore> highscoresLevel1;
        private List<Highscore> highscoresLevel2;
        private List<Highscore> highscoresLevel3;
        private List<Highscore> highscoresLevel4;
        int rank;
        
        // Sonstiges
        private Texture2D entwicklerBg;
        private Texture2D creditsBg;
        private Vector2 entwicklerPosition;
        private Vector2 creditsPosition;
        private Song songMenu;

        private Button buttonPositionIndicator;
        private Texture2D positionIndicator_page1;
        private Texture2D positionIndicator_page2;
        private Vector2 positionIndicatorPosition;

        private bool switchPage = false;
        private float deltax;
        private float deltaXOld;
        private bool switchChoosedPage = false;

        public bool SwitchPage
        {
            get { return switchPage; }
            set { switchPage = value; }
        }

        //welche Menüseite soll geladen werden?
        private int mapChoise;

        public int MapChoise
        {
            get { return mapChoise; }
            set 
            {
                mapChoise = value;                
                switchChoosedPage = true;

                deltax = deltaXOld;
            }
        }

        /// <summary>
        /// Legt fest, dass die Map anfangs nach rechts scrollt
        /// Initialisiert den ViewPort Vektor
        /// Erstellt den Highscore Manager
        /// Leitet den MenuManager zur Oberklasse Page weiter
        /// </summary>
        /// <param name="menuManager">Menümanager zum Wechseln der Seiten</param>
        public MainMenuPage(MenuManager menuManager, int mapChoise)
            : base(menuManager)
        {
            this.mapChoise = mapChoise;
        }

        /// <summary>
        /// Autor: Arne Blumentritt, Mathias Müller
        /// </summary>
        /// <param name="contentManager"></param>
        public override void LoadContent(ContentManager contentManager)
        {
            // Lädt die Texturen
            buttonBgLevel1 = contentManager.Load<Texture2D>("gfx//mainmenu//green_button");
            buttonBgLevel2 = contentManager.Load<Texture2D>("gfx//mainmenu//orange_button");
            buttonBgLevel3 = contentManager.Load<Texture2D>("gfx//mainmenu//red_button");
            buttonBgLevel4 = contentManager.Load<Texture2D>("gfx//mainmenu//ocean_button");
            buttonHelpBg = contentManager.Load<Texture2D>("gfx//mainmenu//blue_minibutton");
            buttonConfigActiveBg = contentManager.Load<Texture2D>("gfx//mainmenu//blue_minibutton_active");
            buttonConfigInactiveBg = contentManager.Load<Texture2D>("gfx//mainmenu//blue_minibutton_inactive");
            highscoreBg = contentManager.Load<Texture2D>("gfx//mainmenu//highscore_background");
            entwicklerBg = contentManager.Load<Texture2D>("gfx//mainmenu//developers");
            creditsBg = contentManager.Load<Texture2D>("gfx//mainmenu//credits");
            positionIndicator_page1 = contentManager.Load<Texture2D>("gfx//mainmenu//pos_page1");
            positionIndicator_page2 = contentManager.Load<Texture2D>("gfx//mainmenu//pos_page2");

            //// Definiert die Positionen der Elemente
            buttonConfigSoundEffectsPosition = new Vector2(Game1.RES_X / 2 - buttonHelpBg.Width / 2, 10);
            buttonHelpPosition = new Vector2(buttonConfigSoundEffectsPosition.X - buttonHelpBg.Width-20, 10);
            buttonConfigSoundBackgroundPosition = new Vector2(buttonConfigSoundEffectsPosition.X + buttonHelpBg.Width + 20, 10);
            positionIndicatorPosition = new Vector2(Game1.RES_X / 2 - positionIndicator_page1.Width / 2, Game1.RES_Y - 40);

            entwicklerPosition = new Vector2(5, Game1.RES_Y - 5 - entwicklerBg.Height);
            creditsPosition = new Vector2(Game1.RES_X - 5 - creditsBg.Width, Game1.RES_Y - 5 - entwicklerBg.Height);

            // Erstellt Buttons
            buttonLevel1 = new Button(Vector2.Zero, buttonBgLevel1, "EASY", Game1.Font_xl);
            buttonLevel2 = new Button(Vector2.Zero, buttonBgLevel2, "MEDIUM", Game1.Font_xl);
            buttonLevel3 = new Button(Vector2.Zero, buttonBgLevel3, "HARD", Game1.Font_xl);
            buttonLevel4 = new Button(Vector2.Zero, buttonBgLevel4, "60 SECONDS", Game1.Font_xl);

            buttonHelp = new Button(buttonHelpPosition, buttonHelpBg, "HELP", Game1.Font_m);

            if (Game1.Config.Sound_background)
                buttonConfigSoundBackground = new Button(buttonConfigSoundBackgroundPosition, buttonConfigActiveBg, "MUSIC", Game1.Font_m);
            else
                buttonConfigSoundBackground = new Button(buttonConfigSoundBackgroundPosition, buttonConfigInactiveBg, "MUSIC", Game1.Font_m);

            if (Game1.Config.Sound_effects)
                buttonConfigSoundEffects = new Button(buttonConfigSoundEffectsPosition, buttonConfigActiveBg, "SOUND", Game1.Font_m);
            else
                buttonConfigSoundEffects = new Button(buttonConfigSoundEffectsPosition, buttonConfigInactiveBg, "SOUND", Game1.Font_m);

            buttonPositionIndicator = new Button(positionIndicatorPosition, positionIndicator_page1);

            // lädt die Musik
            songMenu = contentManager.Load<Song>("sfx/menu");

            InitPositions();
        }

        /// <summary>
        /// Autor: Arne Blumentritt, Mathias Müller
        /// </summary>
        public override void Init()
        {
            if (Game1.Config.Sound_background)
            {
                if (MediaPlayer.State != MediaState.Playing)
                {
                    MediaPlayer.IsRepeating = true;
                    MediaPlayer.Play(songMenu);
                }
            }

            highscoresLevel1 = Game1.HighscoreManager.Read(Game1.Maps.Level1);
            highscoresLevel2 = Game1.HighscoreManager.Read(Game1.Maps.Level2);
            highscoresLevel3 = Game1.HighscoreManager.Read(Game1.Maps.Level3);
            highscoresLevel4 = Game1.HighscoreManager.Read(Game1.Maps.Level4);
        }

        /// <summary>
        /// Autor: Arne Blumentritt, Mathias Müller
        /// </summary>
        public override void Update()
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                Game1.GameState = Game1.GameStates.Exit;
            }

            // Hintergründe aktualisieren
            Game1.BackgroundManager.ScrollSpeed = 2;
            Game1.BackgroundManager.Update();

            //hilfe Button
            buttonHelp.Update();

            if (buttonHelp.IsClicked)
            {
                Game1.MenuManager.CurrentPage = menuManager.HelpPage;
            }


            //config

            buttonConfigSoundEffects.Update();

            if (buttonConfigSoundEffects.IsClicked)
            {
                if (Game1.Config.Sound_effects)
                {
                    Game1.Config.Sound_effects = false;
                    buttonConfigSoundEffects = new Button(buttonConfigSoundEffectsPosition, buttonConfigInactiveBg, "SOUND", Game1.Font_m);
                }
                else
                {
                    Game1.Config.Sound_effects = true;
                    buttonConfigSoundEffects = new Button(buttonConfigSoundEffectsPosition, buttonConfigActiveBg, "SOUND", Game1.Font_m);
                }
            }

            buttonConfigSoundBackground.Update();

            if (buttonConfigSoundBackground.IsClicked)
            {
                if (Game1.Config.Sound_background)
                {
                    Game1.Config.Sound_background = false;
                    buttonConfigSoundBackground = new Button(buttonConfigSoundBackgroundPosition, buttonConfigInactiveBg, "MUSIC", Game1.Font_m);
                }
                else
                {
                    Game1.Config.Sound_background = true;
                    buttonConfigSoundBackground = new Button(buttonConfigSoundBackgroundPosition, buttonConfigActiveBg, "MUSIC", Game1.Font_m);
                }

                if (Game1.Config.Sound_background)
                {
                    MediaPlayer.IsRepeating = true;
                    MediaPlayer.Play(songMenu);
                }
                else
                    MediaPlayer.Stop();
            }

            //seitenwechsel
            if (switchChoosedPage)
            {
                SwitchMenuPage();
            }

            //Wenn die TouchControl HorizontalDrag erkennt, werden die Positionsdaten neu gesetzt
            if (IOTouchControl.IsHorizontalDragRecognized)
            {
                if ((mapChoise == 1 && IOTouchControl.HorizontalDragDeltaX < 0) || (mapChoise == 2 && IOTouchControl.HorizontalDragDeltaX > 0))
                {
                    SlideElements(IOTouchControl.HorizontalDragDeltaX);
                    switchPage = true;
                }

                deltaXOld = IOTouchControl.HorizontalDragDeltaX;
                
            }

            // Positionen der Buttons aktualisieren
            buttonLevel1.Position = new Vector2(positionLevel1.X, 335);
            buttonLevel2.Position = new Vector2(positionLevel2.X, 335);
            buttonLevel3.Position = new Vector2(positionLevel3.X, 335);
            buttonLevel4.Position = new Vector2(positionLevel4.X, 335);

            buttonPositionIndicator.Update();

            // wenn der positionsindikator geklickt wird, wird ein seiten wechsel ausgelöst
            if (buttonPositionIndicator.IsClicked)
            {
                if (mapChoise == 1)
                {
                    deltaXOld = -20;
                    switchPage = true;
                    MapChoise = 2;
                }
                else
                {
                    deltaXOld = 20;
                    switchPage = true;
                    MapChoise = 1;
                }
            }

            if (mapChoise == 1)
            {
                buttonLevel1.Update();
                buttonLevel2.Update();

                if (buttonLevel1.IsClicked)
                {
                    StartLevel(Game1.Maps.Level1);
                }
                if (buttonLevel2.IsClicked)
                {
                    StartLevel(Game1.Maps.Level2);
                }
            }
            if (mapChoise == 2)
            {
                buttonLevel3.Update();
                buttonLevel4.Update();

                if (buttonLevel3.IsClicked)
                {
                    StartLevel(Game1.Maps.Level3);
                }
                if (buttonLevel4.IsClicked)
                {
                    StartLevel(Game1.Maps.Level4);
                }
            }

        }

        /// <summary>
        /// Autor: Arne Blumentritt
        /// </summary>
        /// <param name="spriteBatch"></param>
        public override void Draw(SpriteBatch spriteBatch)
        {
            // Levelhintergrund zeichnen
            Game1.BackgroundManager.Draw(spriteBatch);

            // Buttons in oberer Zeile zeichnen
            buttonHelp.Draw(spriteBatch);
            buttonConfigSoundBackground.Draw(spriteBatch);
            buttonConfigSoundEffects.Draw(spriteBatch);

            // Menüelemente der Level
            DrawMenuElements(positionLevel1, highscoresLevel1, buttonLevel1, buttonBgLevel1, spriteBatch);
            DrawMenuElements(positionLevel2, highscoresLevel2, buttonLevel2, buttonBgLevel2, spriteBatch);
            DrawMenuElements(positionLevel3, highscoresLevel3, buttonLevel3, buttonBgLevel3, spriteBatch);
            DrawMenuElements(positionLevel4, highscoresLevel4, buttonLevel4, buttonBgLevel4, spriteBatch);

            // Untere Zeile zeichnen zeichnen
            spriteBatch.Draw(entwicklerBg, entwicklerPosition, Color.White);
            spriteBatch.Draw(creditsBg, creditsPosition, Color.White);
            buttonPositionIndicator.Draw(spriteBatch);
        }

        /// <summary>
        /// Setzt die Menuelemente auf startPosition.
        /// Autor: Mathias Müller
        /// </summary>
        /// <param name="value">1 = Menuseite 1, 2 = Menuseite 2</param>
        private void SetElementsToStartPosition(int value)
        {
            if (value == 1)
            {
                InitPositions();
            }
            if (value == 2)
            {
                positionLevel1 = new Vector2(15 - Game1.RES_X, 0);
                positionLevel2 = new Vector2(5 - Game1.RES_X / 2, 0);
                positionLevel3 = new Vector2(15, 0);
                positionLevel4 = new Vector2(Game1.RES_X / 2 + 5, 0);
            }
        }

        /// <summary>
        /// Bewegt die Menuelemente um angegebenen delta x über bildschirm
        /// Autor: Mathias Müller
        /// </summary>
        /// <param name="dX">delta x</param>
        private void SlideElements(float dX)
        {
            positionLevel1.X = positionLevel1.X + dX;
            positionLevel2.X = positionLevel2.X + dX;
            positionLevel3.X = positionLevel3.X + dX;
            positionLevel4.X = positionLevel4.X + dX;
        }


        /// <summary>
        /// Startet ein Level
        /// Autor: Arne Blumentritt
        /// </summary>
        /// <param name="level"></param>
        private void StartLevel(Game1.Maps level)
        {
            Game1.LevelManager.CurrentLevelID = level;
            Game1.LevelManager.Init();
            Game1.GameState = Game1.GameStates.Running;
            Game1.ForceUpdate = true;
            // 250ms nach Spielstart Eingaben blockieren, damit Buttonauswahl nicht zu Figuraktion führt
            IOTouchControl.BlockTouchTimer = 250;
        }

        /// <summary>
        /// wechselt die Menu seite
        /// Autor: Mathias Müller
        /// </summary>
        private void SwitchMenuPage()
        {
            // delta x für das wechseln auf das 1. Menu berechnen
            if (mapChoise == 1)
            {
                //wenn abstand zwischen aktueller position und zielposition des buttons größer als delta x
                if ((positionLevel1.X <= 15 - deltaXOld) && (positionLevel3.X >= 15))
                    deltax = deltaXOld;
                //wenn position von buttonlevel3 links von der startposition des linken buttons ist (dahin sollte er sich nicht bewegen)
                //zurücksetzen des seitenwechsels
                else if (positionLevel3.X < 15)
                {
                    deltax = 0;
                    switchChoosedPage = false;
                    mapChoise = 2;
                    SetElementsToStartPosition(2);
                }
                //seitenwechsel abschließen
                else if (positionLevel1.X >= 15)
                {
                    deltax = 0;
                    switchChoosedPage = false;
                }

                buttonPositionIndicator = new Button(positionIndicatorPosition, positionIndicator_page1);
            }
            // delta x für das wechseln auf das 2. Menu berechnen
            if (mapChoise == 2)
            {
                if ((positionLevel3.X >= 15 - deltaXOld) && (positionLevel1.X <= 15))
                    deltax = deltaXOld;
                else if (positionLevel1.X > 15)
                {
                    deltax = 0;
                    switchChoosedPage = false;
                    mapChoise = 1;
                    SetElementsToStartPosition(1);
                }
                else if (positionLevel3.X <= 15)
                {
                    deltax = 0;
                    switchChoosedPage = false;
                }

                buttonPositionIndicator = new Button(positionIndicatorPosition, positionIndicator_page2);
            }
            //neue Positionen der Elemente setzen
            if (mapChoise == 1 || mapChoise == 2)
            {
                SlideElements(deltax);

                if (positionLevel1.X > 15 && mapChoise == 1)
                    SetElementsToStartPosition(1);
                if (positionLevel3.X < 15 && mapChoise == 2)
                    SetElementsToStartPosition(2);
            }
        }

        // Zeichnet alle Menüelemente eines Levels
        // Autor: Arne Blumentritt
        private void DrawMenuElements(Vector2 pos, List<Highscore> highscores, Button button, Texture2D buttonBg, SpriteBatch spriteBatch)
        {
            // Hintergrund Highscore
            spriteBatch.Draw(highscoreBg, new Vector2(pos.X, 90), Color.White);

            // Überschrift Highscore
            spriteBatch.DrawString(Game1.Font_m, "SCORE", new Vector2(pos.X + 70, 92), Color.White);
            spriteBatch.DrawString(Game1.Font_m, "DATE", new Vector2(pos.X + 235, 92), Color.White);

            // Inhalt Highscore
            pos.Y = 94;
            rank = 0;
            foreach (Highscore h in highscores)
            {
                pos.Y += 33;
                rank++;
                spriteBatch.DrawString(Game1.Font_m, rank.ToString() + ".", new Vector2(pos.X + 20, pos.Y), h.isNew ? Color.Yellow : Color.White);
                spriteBatch.DrawString(Game1.Font_m, h.Score.ToString(), new Vector2(pos.X + 82, pos.Y), h.isNew ? Color.Yellow : Color.White);
                spriteBatch.DrawString(Game1.Font_m, h.Time.ToShortDateString(), new Vector2(pos.X + 180, pos.Y), h.isNew ? Color.Yellow : Color.White);
                spriteBatch.DrawString(Game1.Font_m, h.Time.ToShortTimeString(), new Vector2(pos.X + 290, pos.Y), h.isNew ? Color.Yellow : Color.White);
            }

            // Startbutton
            button.Draw(spriteBatch);
        }

        // Initalisiert die Positionen der Menüelemente
        // Autor: Arne Blumentritt
        private void InitPositions()
        {
            positionLevel1 = new Vector2(15, 0);
            positionLevel2 = new Vector2(Game1.RES_X / 2 + 5, 0);
            positionLevel3 = new Vector2(Game1.RES_X + 15, 0);
            positionLevel4 = new Vector2(Game1.RES_X + Game1.RES_X / 2 + 5, 0);
        }
    }
}
